﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using tactics.Interfaces;
using tactics.Events;

namespace tactics.Abilities
{
    using Coord = Utility.Pair<int, int>;

    public class AbilityComponent
    {
        public List<IAbilityComponent> onHit;
        public List<IAbilityComponent> onMiss;

        public int bonus;
        public DefenseType defenseType;
        public int radius;

        public AbilityComponent()
        {
            onHit = new List<IAbilityComponent>();
            onMiss = new List<IAbilityComponent>();
        }
    }

    public class Ability
    {
        List<AbilityComponent> components;

        int id;
        string name;
        string description;
        int range;
        bool aoe;

        #region Properties

        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public string Description
        {
            get { return description; }
            set { description = value; }
        }

        public int Range
        {
            get { return range; }
            set { range = value; }
        }

        public bool HasAoEComponent
        {
            get { return aoe; }
        }

        public List<AbilityComponent> Components
        {
            get { return components; }
        }

        #endregion

        public Ability()
        {
            aoe = false;
            components = new List<AbilityComponent>();
        }

        public void AddComponent(AbilityComponent component)
        {
            components.Add(component);
            if (component.radius > 0)
                aoe = true;
        }

        public void UseAbility(Unit unit)
        {
            foreach (AbilityComponent component in components)
            {
                UseComponentOnUnit(component, unit);
            }
        }

        public void UseAoEAbility(Coord coord)
        {
            var units = new List<Unit>();

            foreach (Player p in TacticsEngine.Instance.Game.Players)
                units.AddRange(p.Units);

            foreach (AbilityComponent component in components)
            {
                Coord min = new Coord(coord.First - component.radius, coord.Second - component.radius);
                Coord max = new Coord(coord.First + component.radius, coord.Second + component.radius);

                foreach (Unit u in units)
                {
                    if ((u.X >= min.First && u.X <= max.First) &&
                        (u.Y >= min.Second && u.Y <= max.Second))
                    {
                        UseComponentOnUnit(component, u);
                    }
                }
            }
        }

        private void UseComponentOnUnit(AbilityComponent component, Unit unit) 
        {
            bool hit = true; //TODO: roll to hit here

            if (hit)
            {
                foreach (IAbilityComponent ability in component.onHit)
                {
                    ability.UseAbility(unit);
                }
                unit.TriggerHit();
            }
            else
            {
                foreach (IAbilityComponent ability in component.onMiss)
                {
                    ability.UseAbility(unit);
                }
                unit.TriggerMiss();
            }
        }
    }
}
